﻿#include "widget.h"
#include "ui_widget.h"

#include <QSerialPortInfo>
#include <QDebug>
#include <QString>
#include <QMessageBox>
#include <QFileDialog>
#include <QDateTime>
#include <QThread>
#include "mycombobox.h"

#pragma execution_character_set("utf-8")
Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    this->setLayout(ui->gridLayout_global);

    serialPort = new QSerialPort();
    timer = new QTimer(this);
    ui->comboBox_bote->setCurrentIndex(6);
    ui->comboBox_data->setCurrentIndex(4);

    serialState = false;
    ui->btn_send->setEnabled(false);
    ui->checkBox_autoSend->setEnabled(false);
    ui->lineEdit_autoSendTime->setEnabled(false);
    ui->lineEdit_send->setEnabled(false);
    ui->checkBox_sendHEX->setEnabled(false);
    ui->checkBox_sendNewLine->setEnabled(false);
    QTimer *mySysTime = new QTimer(this);


    connect(serialPort,&QSerialPort::readyRead,this,&Widget::on_recvData);
    connect(timer,&QTimer::timeout,this,&Widget::on_btn_send_clicked);
    connect(mySysTime,&QTimer::timeout,this,&Widget::getSysTime);
    connect(ui->comboBox_ser,&Mycombobox::lefeClicked,this,&Widget::refresh_serPort);
    // 使用 多线程实现循环发送
    myThread = new MyCustomThread(this);
    connect(myThread,&MyCustomThread::threadTimeout,this,&Widget::on_timerConButton);
    /*
     * 使用定时器实现循环发送
    buttonConTimer = new QTimer(this);
    connect(buttonConTimer,&QTimer::timeout,this,&Widget::on_timerConButton);
    */
    refresh_serPort();
    mySysTime->start(1000);
    sendCountTotal = 0;
    recvCountTotal = 0;
    recvTimeState = 0;
    btnCount = 0;


    for (int i = 1; i <= 10; i++) {
        QString btnName = QString("pushButton_%1").arg(i);
        QPushButton* btn = findChild<QPushButton *>(btnName);
        if(btn){
            btn->setProperty("buttonID",i);
            buttons.append(btn);
            connect(btn,&QPushButton::clicked,this,&Widget::on_command_button_clicked);
        }
        QString lineditName = QString("lineEdit_%1").arg(i);
        QLineEdit* linedit = findChild<QLineEdit*>(lineditName);
        lineEdits.append(linedit);

        QString checkboxName = QString("checkBox_%1").arg(i);
        QCheckBox* checkbox = findChild<QCheckBox*>(checkboxName);
        checkBoxs.append(checkbox);

    }

}

Widget::~Widget()
{
    delete ui;
}


void Widget::on_btn_openCloseSer_clicked()
{
    if(serialState == 0) //串口被打开
    {
        // 选择串口
        serialPort->setPortName(ui->comboBox_ser->currentText());
        // 设置波特率
        serialPort->setBaudRate(ui->comboBox_bote->currentText().toUInt());
        // 设置数据位
        serialPort->setDataBits( QSerialPort::DataBits(ui->comboBox_data->currentText().toUInt()));
        // 设置校验位
        switch (ui->comboBox_check->currentIndex()) {
        case 0:
            serialPort->setParity(QSerialPort::NoParity);
            break;
        case 1:
            serialPort->setParity(QSerialPort::EvenParity);
            break;
        case 2:
            serialPort->setParity(QSerialPort::OddParity);
            break;
        case 3:
            serialPort->setParity(QSerialPort::SpaceParity);
            break;
        case 4:
            serialPort->setParity(QSerialPort::MarkParity);
            break;
        default:
            break;
        }
        // 设置停止位
        serialPort->setStopBits(QSerialPort::StopBits(ui->comboBox_stop->currentText().toUInt()));

        // 设置流控
        if(ui->comboBox_flow->currentText() == "NoFlow"){
            serialPort->setFlowControl(QSerialPort::NoFlowControl);
        }
        // 打开串口
        if(serialPort->open(QSerialPort::ReadWrite)) {
            ui->comboBox_bote->setEnabled(false);
            ui->comboBox_check->setEnabled(false);
            ui->comboBox_data->setEnabled(false);
            ui->comboBox_flow->setEnabled(false);
            ui->comboBox_ser->setEnabled(false);
            ui->comboBox_stop->setEnabled(false);
            ui->btn_openCloseSer->setText("关闭串口");
            ui->btn_send->setEnabled(true);
            serialState = 1;
            ui->checkBox_autoSend->setEnabled(true);
            ui->lineEdit_autoSendTime->setEnabled(true);
            ui->lineEdit_send->setEnabled(true);
            ui->checkBox_sendHEX->setEnabled(true);
            ui->checkBox_sendNewLine->setEnabled(true);
            ui->label_sendState->setText(ui->comboBox_ser->currentText() + " isopen!");
        }else{
            QMessageBox msgBox;
            msgBox.setWindowTitle("错误");
            msgBox.setText("串口打开错误，串口已占用或被拔出");
            msgBox.exec();
        }

    }else {
        serialPort->close();
        ui->comboBox_bote->setEnabled(true);
        ui->comboBox_check->setEnabled(true);
        ui->comboBox_data->setEnabled(true);
        ui->comboBox_flow->setEnabled(true);
        ui->comboBox_ser->setEnabled(true);
        ui->comboBox_stop->setEnabled(true);
        ui->btn_openCloseSer->setText("打开串口");
        ui->btn_send->setEnabled(false);
        serialState = 0;
        ui->checkBox_autoSend->setEnabled(false);
        ui->lineEdit_autoSendTime->setEnabled(false);
        ui->lineEdit_send->setEnabled(false);
        ui->checkBox_sendHEX->setEnabled(false);
        ui->checkBox_sendNewLine->setEnabled(false);
        timer->stop();
        ui->label_sendState->setText(ui->comboBox_ser->currentText() + " notopen!");
        ui->checkBox_autoSend->setCheckState(Qt::Unchecked);
    }
}

void Widget::on_btn_send_clicked()
{
    int sendCount = 0;
    const char* sendData;
    QByteArray ba = ui->lineEdit_send->text().toLatin1();
    sendData = ba.data();

    if(ui->checkBox_sendHEX->isChecked()){
        // 获取输入框内容
        QString temp = ui->lineEdit_send->text();
        // 转化为qbytearray
        QByteArray hexTemp = temp.toUtf8().toUpper();
        // 判断是否为16进制格式
        if(hexTemp.size() %2 != 0)
        {
            ui->label_sendState->setText("Input Error!");
            return;
        }
        for(char c : hexTemp)
        {
            if(!std::isxdigit(c)){
                ui->label_sendState->setText("Input Error!");
                return;
            }
        }

        if(ui->checkBox_sendNewLine->isChecked())
            hexTemp.append("\r\n");
        // 转换为hex
        QByteArray sendhex = QByteArray::fromHex(hexTemp);


        // 发送
        sendCount = serialPort->write(sendhex);

    }else {
        // 发送非十六进制
        QByteArray sendtemp = QByteArray(sendData);
        if(ui->checkBox_sendNewLine->isChecked())
            sendtemp.append("\r\n");
        sendCount = serialPort->write(sendtemp);
    }


    if(sendCount == -1){
        ui->label_sendState->setText("SEND ERROR!");
    }else{
        ui->label_sendState->setText("Send OK!");
        sendCountTotal += sendCount;
        ui->label_sendCount->setText("Send: " + QString::number(sendCountTotal));
        if(strcmp(sendData,sendBak.toStdString().c_str()) != 0)
        {
            ui->textEdit_history->append(sendData);
            sendBak = QString(sendData);
        }
        ui->textEdit_Rec->moveCursor(QTextCursor::End);
        ui->textEdit_Rec->ensureCursorVisible();
    }
}

void Widget::on_recvData()
{

    QString recvMessage =  serialPort->readAll();
    if(recvMessage != NULL){
        if(ui->checkBox_autoChangeLine->isChecked()) recvMessage.append("\r\n");

        if(ui->checkBox_HEX->isChecked()){ //HEX接手按钮被按下
            //读取当前框内的数据
            QString temphex = ui->textEdit_Rec->toPlainText();
            // 将新接收到的转换为hex
            QByteArray btemphex = recvMessage.toUtf8().toHex().toUpper();
            QString lasttemp = QString::fromUtf8(btemphex);
            QString lastShow;
            for(int i = 0;i< lasttemp.size();i += 2){
                lastShow += lasttemp.mid(i,2)+" ";
            }
            // 组合后的数据进行展示
            ui->textEdit_Rec->setText(temphex + lastShow);

        }else {
            if(recvTimeState == 1){
                QString recvMessageTime = "【" + myTime + "】" + recvMessage;
                ui->textEdit_Rec->insertPlainText(recvMessageTime);
            }else {
                ui->textEdit_Rec->insertPlainText(recvMessage);
            }
        }
        recvCountTotal += recvMessage.size();
        ui->label_recvCount->setText("Receive: " + QString::number(recvCountTotal));
    }
    ui->textEdit_Rec->moveCursor(QTextCursor::End);
    ui->textEdit_Rec->ensureCursorVisible();
}

void Widget::on_checkBox_autoSend_clicked(bool checked)
{
    if(checked)//被选中
    {
        qDebug() << "checked checked";
        int sendtime = ui->lineEdit_autoSendTime->text().toInt();
        timer->start(sendtime);
        ui->lineEdit_autoSendTime->setEnabled(false);
        ui->lineEdit_send->setEnabled(false);
        ui->btn_send->setEnabled(false);
    }else {//取消选中
        timer->stop();
        ui->lineEdit_autoSendTime->setEnabled(true);
        ui->lineEdit_send->setEnabled(true);
        ui->btn_send->setEnabled(true);
    }
}

void Widget::on_btn_revClear_clicked()
{
    ui->textEdit_Rec->setText("");
}

void Widget::on_btn_revSave_clicked()
{
    QString fileName = QFileDialog::getSaveFileName(this, tr("Save File"),
                                                    "D:/QTStudy/study/studySerial/serialData",
                                                    tr("Text files (*.txt)"));
    if(fileName != NULL){
        QFile file(fileName);
        if (!file.open(QIODevice::WriteOnly | QIODevice::Text))
            return;

        QTextStream out(&file);
        out << ui->textEdit_Rec->toPlainText();
        file.close();

    }

}

void Widget::getSysTime()
{
    QDateTime dateTime = QDateTime::currentDateTime();
    QDate date = dateTime.date();
    int year = date.year();
    int mounth = date.month();
    int day = date.day();

    QTime time = dateTime.time();
    int hour = time.hour();
    int minute = time.minute();
    int second = time.second();

    myTime = QString("%1-%2-%3 %4:%5:%6")
            .arg(year,2,10,QChar('0'))
            .arg(mounth,2,10,QChar('0'))
            .arg(day,2,10,QChar('0'))
            .arg(hour,2,10,QChar('0'))
            .arg(minute,2,10,QChar('0'))
            .arg(second,2,10,QChar('0'));
    ui->label_currenttime->setText(myTime);
    saveTime = QString("%1-%2-%3").arg(year,2,10,QChar('0'))
            .arg(mounth,2,10,QChar('0'))
            .arg(day,2,10,QChar('0'));
}

void Widget::on_checkBox_revTime_clicked(bool checked)
{
    if(checked){
        recvTimeState = 1;
    }else {
        recvTimeState = 0;
    }

}

void Widget::on_checkBox_HEX_clicked(bool checked)
{
    if(checked){ //转换为hex显示
        // 读取框内容
        QString temp = ui->textEdit_Rec->toPlainText();
        // 转换为hex
        // 转换为qbytearray
        QByteArray qtemp = temp.toUtf8();
        // 转化为HEX
        QByteArray qHextemp = qtemp.toHex();

        QString lastShow ;
        temp   = QString::fromUtf8(qHextemp);
        for(int i = 0;i< temp.size();i+=2){
            lastShow += temp.mid(i,2) +" ";
        }

        // 显示 QBytearray 要转化为QString
        ui->textEdit_Rec->setText(lastShow.toUpper());
    }else {
        // 读取框内容
        QString hextemp = ui->textEdit_Rec->toPlainText();
        // 转化为QBytearray
        QByteArray qhextemp = hextemp.toUtf8();
        // 从HEX转化回来
        QByteArray qstrtemp = QByteArray::fromHex(qhextemp);

        ui->textEdit_Rec->setText(QString::fromUtf8(qstrtemp));


    }
}

void Widget::on_btn_hideBoard_clicked(bool checked)
{
    if(checked){
        //        ui->groupBox_rec->hide();
        ui->groupBox_text->hide();
        ui->btn_hideBoard->setText("显示文本");

    }else {
        ui->groupBox_text->show();
        ui->btn_hideBoard->setText("隐藏文本");

    }
}

void Widget::on_btn_hidHistory_clicked(bool checked)
{
    if(checked){
        ui->groupBox_history->hide();
        ui->btn_hidHistory->setText("显示历史");
    }else {
        ui->groupBox_history->show();
        ui->btn_hidHistory->setText("隐藏历史");
    }
}

void Widget::refresh_serPort()
{
    ui->comboBox_ser->clear();
    QList<QSerialPortInfo> serialport = QSerialPortInfo::availablePorts();
    for(QSerialPortInfo serialPortInfo : serialport){
        ui->comboBox_ser->addItem(serialPortInfo.portName());
    }
    ui->label_sendState->setText("serial port refresh!");
}

void Widget::on_command_button_clicked()
{
    //确定消息的发送者
    QPushButton *btn = qobject_cast<QPushButton *>(sender());
    if(btn){
        int num = btn->property("buttonID").toInt();//取出加入属性中的值

        QString lineEditName = QString("lineEdit_%1").arg(num);
        QLineEdit *lineEdie = findChild<QLineEdit *>(lineEditName);
        if(lineEdie){
            if(lineEdie->text().size() <= 0){
                return;
            }
            ui->lineEdit_send->setText(lineEdie->text());
        }

        QString checkBoxName = QString("checkBox_%1").arg(num);
        QCheckBox * checkBox = findChild<QCheckBox *>(checkBoxName);
        if(checkBox){
            ui->checkBox_sendHEX->setChecked(checkBox->isChecked());
        }
        on_btn_send_clicked();
    }
}
/*
void Widget::on_pushButton_clicked()
{
    ui->lineEdit_send->setText(ui->lineEdit->text());
    ui->checkBox_sendHEX->setChecked(ui->checkBox->isChecked());
    on_btn_send_clicked();
}

void Widget::on_pushButton_2_clicked()
{
    ui->lineEdit_send->setText(ui->lineEdit_2->text());
    ui->checkBox_sendHEX->setChecked(ui->checkBox_2->isChecked());
    on_btn_send_clicked();
}

void Widget::on_pushButton_3_clicked()
{
    ui->lineEdit_send->setText(ui->lineEdit_3->text());
    ui->checkBox_sendHEX->setChecked(ui->checkBox_3->isChecked());
    on_btn_send_clicked();
}

void Widget::on_pushButton_4_clicked()
{
    ui->lineEdit_send->setText(ui->lineEdit_4->text());
    ui->checkBox_sendHEX->setChecked(ui->checkBox_4->isChecked());
    on_btn_send_clicked();
}

void Widget::on_pushButton_5_clicked()
{
    ui->lineEdit_send->setText(ui->lineEdit_5->text());
    ui->checkBox_sendHEX->setChecked(ui->checkBox_5->isChecked());
    on_btn_send_clicked();
}

void Widget::on_pushButton_6_clicked()
{
    ui->lineEdit_send->setText(ui->lineEdit_6->text());
    ui->checkBox_sendHEX->setChecked(ui->checkBox_6->isChecked());
    on_btn_send_clicked();
}

void Widget::on_pushButton_7_clicked()
{
    ui->lineEdit_send->setText(ui->lineEdit_7->text());
    ui->checkBox_sendHEX->setChecked(ui->checkBox_7->isChecked());
    on_btn_send_clicked();
}

void Widget::on_pushButton_8_clicked()
{
    ui->lineEdit_send->setText(ui->lineEdit_8->text());
    ui->checkBox_sendHEX->setChecked(ui->checkBox_8->isChecked());
    on_btn_send_clicked();
}

void Widget::on_pushButton_9_clicked()
{
    ui->lineEdit_send->setText(ui->lineEdit_9->text());
    ui->checkBox_sendHEX->setChecked(ui->checkBox_9->isChecked());
    on_btn_send_clicked();
}

void Widget::on_pushButton_10_clicked()
{
    ui->lineEdit_send->setText(ui->lineEdit_10->text());
    ui->checkBox_sendHEX->setChecked(ui->checkBox_10->isChecked());
    on_btn_send_clicked();
}
*/

void Widget::on_checkBox_recycleSend_clicked(bool checked)
{
    if(checked){
        //        buttonConTimer->start(ui->spinBox_delayTime->text().toInt()); //使用定时器实现循环发送
        myThread->start();  //使用多线程实现循环发送
        ui->spinBox_delayTime->setEnabled(false);
    }else {
        //        buttonConTimer->stop(); // 使用定时器实现循环发送
        //        myThread->wait();
        myThread->quit();
        myThread->deleteLater(); // 使用多线程实现循环发送
        btnCount = 0;
        ui->spinBox_delayTime->setEnabled(true);
    }
}

void Widget::on_timerConButton()
{
    /*
    for (int  i= 0;  i< buttons.size(); i++) {
        QPushButton *btnTem = buttons[i];
        emit btnTem->clicked();
        QThread::msleep(ui->spinBox_delayTime->text().toInt());//不能在QT的UI界面中延时，否则会导致页面刷新问题！
    }*/
    if(btnCount < buttons.size()){
        QPushButton *btnTem = buttons[btnCount];
        emit btnTem->clicked();
        btnCount = btnCount +1;
    }else {
        btnCount = 0;
    }
}

void Widget::on_btnInit_clicked()
{
    QMessageBox msgBox;
    msgBox.setWindowTitle("提示");
    msgBox.setIcon(QMessageBox::Question);
    msgBox.setText("重置操作不可逆，是否重置?");
    //    msgBox.setStandardButtons(QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel);
    //    msgBox.setDefaultButton(QMessageBox::Save);
    QPushButton* yesbutton =  msgBox.addButton("是",QMessageBox::YesRole);
    QPushButton* nobutton =  msgBox.addButton("否",QMessageBox::NoRole);
    msgBox.exec();
    if(msgBox.clickedButton() == yesbutton){
        for (int i = 0; i < lineEdits.size(); i++) {
            lineEdits[i]->clear();
            checkBoxs[i]->setCheckable(false);
        }
    }
    if(msgBox.clickedButton() == nobutton){
        qDebug()<<"noooooo";
    }

}

void Widget::on_btnSave_clicked()
{
    QString fileName = QFileDialog::getSaveFileName(this, tr("Save File"),
                                                    QString("D:/texttest/%1").arg(saveTime),
                                                    tr("Text files (*.txt)"));
    QFile file(fileName);
    if (!file.open(QIODevice::WriteOnly | QIODevice::Text))
        return;

    QTextStream out(&file);
    for(int i = 0;i < lineEdits.size();i++){
        out << checkBoxs[i]->isChecked() << "," << lineEdits[i]->text() <<"\n";
    }
    file.close();
}

void Widget::on_btnLoad_clicked()
{
    int i = 0;
    QString fileName = QFileDialog::getOpenFileName(this, tr("Open File"),
                                                    "D:/texttest",
                                                    tr("Text files (*.txt)"));
    QFile file(fileName);
    if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
        return;
    QTextStream in(&file);
    while (!in.atEnd()) {
        QString line = in.readLine();
        QStringList list = line.split(",");
        if(list.count() == 2){
            checkBoxs[i]->setChecked(list[0].toInt());
            lineEdits[i]->setText(list[1]);
        }
        i++;
    }
    file.close();

}
